package com.it.xuehang.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.it.xuehang.entity.CityInfo;
import com.it.xuehang.entity.DailyWeatherForecast;
import com.it.xuehang.entity.SyncLog;
import com.it.xuehang.entity.YesterdayWeather;
import com.it.xuehang.mapper.CityInfoMapper;
import com.it.xuehang.mapper.DailyWeatherForecastMapper;
import com.it.xuehang.mapper.SyncLogMapper;
import com.it.xuehang.mapper.YesterdayWeatherMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Service
public class WeatherSyncServiceOld {

    private static final Logger logger = LoggerFactory.getLogger(WeatherSyncServiceOld.class);

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private YesterdayWeatherMapper yesterdayWeatherMapper;
    @Autowired
    private SyncLogMapper syncLogMapper;
    @Autowired
    private CityInfoMapper cityInfoMapper;
    @Autowired
    private DailyWeatherForecastMapper dailyWeatherForecastMapper;

    // 每天凌晨3点执行一次同步任务
   // @Scheduled(cron = "0 0 3 * * ?")
    //5s执行一次
    //@Scheduled(cron = "*/5 * * * * ?")
    public void syncWeatherData() {
        try {
            String url = "http://t.weather.sojson.com/api/weather/city/101020100";
            Map<String, Object> response = restTemplate.getForObject(url, Map.class);
            logger.info("response:{}", response);

            // 解析城市信息
            Map<String, Object> cityInfo = (Map<String, Object>) response.get("cityInfo");
            logger.info("cityInfo:{}", cityInfo);

            LambdaQueryWrapper<CityInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CityInfo::getCityId, cityInfo.get("citykey").toString());
            CityInfo dbCity = cityInfoMapper.selectOne(wrapper);
            logger.info("dbCity:{}", dbCity);

            boolean shouldUpdateAll = false; // 标志是否需要更新所有相关数据
            if (dbCity == null || !dbCity.getUpdateTime().equals(cityInfo.get("updateTime"))) {
                shouldUpdateAll = true;
            }

            if (shouldUpdateAll) {
                // 更新城市信息
                if (dbCity == null) {
                    dbCity = new CityInfo();
                    dbCity.setCityId(cityInfo.get("citykey").toString());
                }
                dbCity.setCity(cityInfo.get("city").toString());
                dbCity.setParentCity(cityInfo.get("parent").toString());
                dbCity.setUpdateTime(cityInfo.get("updateTime").toString());

                //如果城市存在而且当时天气变化，更新信息
                if (dbCity.getId() != null && cityInfoMapper.selectById(dbCity.getId()) != null) {
                    cityInfoMapper.updateById(dbCity);
                }else{
                    //城市不存在，插入
                    logger.info("cityInfoMapper.insert(dbCity)前dbCity数值：{}",dbCity);
                    cityInfoMapper.insert(dbCity);
                    logger.info("cityInfoMapper.insert(dbCity)后dbCity数值：{}",dbCity);
                }

                // 解析并强制更新昨天的天气数据
                Map<String, Object> data = (Map<String, Object>) response.get("data");
                Map<String, Object> yesterdayData = (Map<String, Object>) data.get("yesterday");
                saveYesterdayWeather(dbCity.getId(), yesterdayData, true); // 强制更新

                // 解析并强制更新今天的天气预报数据及未来几天的天气预报数据
                List<Map<String, Object>> forecastList = (List<Map<String, Object>>) data.get("forecast");

                for (int i = 0; i < forecastList.size(); i++) {
                    Map<String, Object> dailyForecast = forecastList.get(i);
                    saveDailyWeatherForecast(dbCity.getId(), dailyForecast, data, i, true); // 强制更新
                }
            } else {

                // 如果不需要更新所有数据，只进行常规的保存操作（每次查询都更新为最新的天气数据）
                Map<String, Object> data = (Map<String, Object>) response.get("data");
                Map<String, Object> yesterdayData = (Map<String, Object>) data.get("yesterday");
                //昨天的天气已经不会改变，不需要更新，false
                saveYesterdayWeather(dbCity.getId(), yesterdayData, true);

                List<Map<String, Object>> forecastList = (List<Map<String, Object>>) data.get("forecast");

                for (int i = 0; i < forecastList.size(); i++) {
                    Map<String, Object> dailyForecast = forecastList.get(i);
                    saveDailyWeatherForecast(dbCity.getId(), dailyForecast, data, i, true);
                }
            }

            // 记录同步成功日志
            SyncLog syncLog = new SyncLog();
            syncLog.setStatus("success");
            syncLog.setMessage("Successfully synced weather data for " + dbCity.getCity());
            syncLog.setSyncTime(LocalDateTime.now());
            syncLogMapper.insert(syncLog);

            logger.info("Synchronization completed successfully.");

        } catch (Exception e) {
            // 记录同步失败日志
            SyncLog syncLog = new SyncLog();
            syncLog.setStatus("failed");
            syncLog.setMessage("Failed to sync weather data: " + e.getMessage());
            syncLog.setSyncTime(LocalDateTime.now());
            syncLogMapper.insert(syncLog);
            logger.error("Synchronization failed.", e);
        }
    }

    private void saveYesterdayWeather(BigDecimal cityId, Map<String, Object> data, boolean forceUpdate) {
        LocalDate date = LocalDate.parse(data.get("ymd").toString());

        if (!forceUpdate && yesterdayWeatherMapper.existsByCityIdAndDate(cityId, date) > 0) {
            return;
        }

        // 清除旧的数据，保证数据唯一性
        if (forceUpdate) {
            yesterdayWeatherMapper.delete(new LambdaQueryWrapper<YesterdayWeather>()
                    .eq(YesterdayWeather::getCityId, cityId)
                    .eq(YesterdayWeather::getDate, date));
        }

        YesterdayWeather yesterdayWeather = new YesterdayWeather();
        yesterdayWeather.setCityId(cityId);
        yesterdayWeather.setDate(date);
        yesterdayWeather.setWeek(data.get("week").toString());
        yesterdayWeather.setSunrise(data.get("sunrise").toString());
        yesterdayWeather.setHighTemp(new BigDecimal(data.get("high").toString().replace("高温 ", "").replace("℃", "")));
        yesterdayWeather.setLowTemp(new BigDecimal(data.get("low").toString().replace("低温 ", "").replace("℃", "")));
        yesterdayWeather.setSunset(data.get("sunset").toString());
        yesterdayWeather.setAqi(new BigDecimal(data.get("aqi").toString()));
        yesterdayWeather.setWindDirection(data.get("fx").toString());
        yesterdayWeather.setWindStrength(data.get("fl").toString());
        yesterdayWeather.setWeatherType(data.get("type").toString());
        yesterdayWeather.setNotice(data.get("notice").toString());

        yesterdayWeatherMapper.insert(yesterdayWeather);
    }

    private void saveDailyWeatherForecast(BigDecimal cityId, Map<String, Object> data, Map<String, Object> currentData, int dayOffset, boolean forceUpdate) {
        logger.info("Before calculation, dayOffset: {}", dayOffset);
        LocalDate forecastDate = LocalDate.parse(data.get("ymd").toString());
        //.plusDays(dayOffset);
        logger.info("After calculation, dayOffset: {}", dayOffset);
        logger.info("forecastDate: {}", forecastDate);


        if (!forceUpdate && dailyWeatherForecastMapper.existsByCityIdAndForecastDate(cityId, forecastDate) > 0) {
            return;
        }

        // 清除旧的数据，保证数据唯一性
        if (forceUpdate) {
            dailyWeatherForecastMapper.delete(new LambdaQueryWrapper<DailyWeatherForecast>()
                    .eq(DailyWeatherForecast::getCityId, cityId)
                    .eq(DailyWeatherForecast::getForecastDate, forecastDate));
        }

        DailyWeatherForecast forecast = new DailyWeatherForecast();
        forecast.setCityId(cityId);
        forecast.setForecastDate(forecastDate);
        forecast.setWeek(data.get("week").toString());
        forecast.setSunrise(data.get("sunrise").toString());
        forecast.setHighTemp(new BigDecimal(data.get("high").toString().replace("高温 ", "").replace("℃", "")));
        forecast.setLowTemp(new BigDecimal(data.get("low").toString().replace("低温 ", "").replace("℃", "")));
        forecast.setSunset(data.get("sunset").toString());
        forecast.setAqi(new BigDecimal(data.get("aqi").toString()));
        forecast.setWindDirection(data.get("fx").toString());
        forecast.setWindStrength(data.get("fl").toString());
        forecast.setWeatherType(data.get("type").toString());
        forecast.setNotice(data.get("notice").toString());
        forecast.setSystemUpdateTime(LocalDateTime.now()); // 系统更新时间

        // Additional fields from 'currentData' object
        forecast.setHumidity(currentData.get("shidu").toString());
        forecast.setPm25(new BigDecimal(currentData.get("pm25").toString()));
        forecast.setPm10(new BigDecimal(currentData.get("pm10").toString()));
        forecast.setAirQuality(currentData.get("quality").toString());
        forecast.setTemperature(currentData.get("wendu").toString());
        forecast.setColdIndex(currentData.get("ganmao").toString());

        dailyWeatherForecastMapper.insert(forecast);
    }


}